package com.tong.lettuce.lock.interceptor;

import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.context.expression.CachedExpressionEvaluator;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.lang.Nullable;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RedisLockExpressionEvaluator extends CachedExpressionEvaluator {

    private final Map<CachedExpressionEvaluator.ExpressionKey, Expression> keyCache = new ConcurrentHashMap<>(64);

    /**
     * Create an {@link EvaluationContext}.
     * @param target the target object
     * @param method the method
     * @param args the method arguments
     * @return the evaluation context
     */
    public EvaluationContext createEvaluationContext(Object target, Method method, Object[] args) {
        return new RedisLockEvaluationContext(target, method, args);
    }

    @Nullable
    public Object key(String keyExpression, AnnotatedElementKey methodKey, EvaluationContext evalContext) {
        return getExpression(this.keyCache, methodKey, keyExpression).getValue(evalContext);
    }

    /**
     *
     */
    public static class RedisLockEvaluationContext extends MethodBasedEvaluationContext {

        private static final ParameterNameDiscoverer NAME_DISCOVERER = new DefaultParameterNameDiscoverer();

        public RedisLockEvaluationContext(Object rootObject, Method method, Object[] arguments) {
            super(rootObject, method, arguments, NAME_DISCOVERER);
        }

    }


}
